﻿// <copyright file="ShapeExtensions.cs" company="Edge Extensions Project">
// Copyright (c) 2009 All Rights Reserved
// </copyright>
// <author>Kevin Nessland</author>
// <email>kevinnessland@gmail.com</email>
// <date>2009-07-08</date>
// <summary>Contains Shape-related extension methods.</summary>
namespace Edge.Extensions.Wpf
{
    using System.Runtime.InteropServices;
    using System.Windows.Media;

    /// <summary>
    /// Contains various Shape-related extensions.
    /// </summary>
    public static class ShapeExtensions
    {
        /// <summary>
        /// Calculates the left percentage from a center point within a rectangle.  The further the mouse 
        /// is from the center, the higher the percentage.
        /// </summary>
        /// <param name="rect">Rectangle that represents the bounds.</param>
        /// <returns>Left percentage from center.</returns>
        public static double MousePercentageFromCenterLeft(this System.Windows.Shapes.Rectangle rect)
        {
            System.Windows.Point point1 = GetMousePosition(rect);

            double positionX = point1.X;

            double containerWidth = rect.Width;

            double centerX = containerWidth / 2;

            double percentageX = positionX.PercentageOf(centerX);

            return 100 - percentageX;
        }

        /// <summary>
        /// Calculates the top percentage from a center point within a rectangle.  The further the mouse 
        /// is from the center, the higher the percentage.
        /// </summary>
        /// <param name="rect">Rectangle that represents the bounds.</param>
        /// <returns>Top percentage from center.</returns>
        public static double MousePercentageFromCenterTop(this System.Windows.Shapes.Rectangle rect)
        {
            System.Windows.Point point1 = GetMousePosition(rect);

            double positionY = point1.Y;

            double containerHeight = rect.Height;

            double centerY = containerHeight / 2;

            double percentageY = positionY.PercentageOf(centerY);

            return 100 - percentageY;
        }

        /// <summary>
        /// Calculates the right percentage from a center point within a rectangle.  The further the mouse 
        /// is from the center, the higher the percentage.
        /// </summary>
        /// <param name="rect">Rectangle that represents the bounds.</param>
        /// <returns>Right percentage from center.</returns>
        public static double MousePercentageFromCenterRight(this System.Windows.Shapes.Rectangle rect)
        {
            return rect.MousePercentageFromCenterLeft() * -1;
        }

        /// <summary>
        /// Calculates the bottom percentage from a center point within a rectangle.  The further the mouse 
        /// is from the center, the higher the percentage.
        /// </summary>
        /// <param name="rect">Rectangle that represents the bounds.</param>
        /// <returns>Bottom percentage from center.</returns>
        public static double MousePercentageFromCenterBottom(this System.Windows.Shapes.Rectangle rect)
        {
            return rect.MousePercentageFromCenterTop() * -1;
        }

        /// <summary>
        /// Retrieves an accurate mouse position relative to another object.
        /// </summary>
        /// <param name="relativeTo">Object that acts as the mouse bounds.</param>
        /// <returns>Point representing the position of the mouse.</returns>
        public static System.Windows.Point GetMousePosition(Visual relativeTo)
        {
            Win32Point mousePoint = new Win32Point();
            GetCursorPos(ref mousePoint);
            return relativeTo.PointFromScreen(new System.Windows.Point(mousePoint.X, mousePoint.Y));
        }

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool GetCursorPos(ref Win32Point pt);

        /// <summary>
        /// Contains point information.
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        internal struct Win32Point
        {
            /// <summary>
            /// Position on x-axis.
            /// </summary>
            public int X;

            /// <summary>
            /// Position on y-axis.
            /// </summary>
            public int Y;
        }
    }
}
